home *** CD-ROM | disk | FTP | other *** search
/ PC World 2008 September / PCWorld_2008-09_cd.bin / v cisle / sadanastroju / lightning-0.8-tb-win.xpi / js / calWeekPrinter.js < prev    next >
Text File  |  2007-10-29  |  11KB  |  282 lines

  1. /* -*- Mode: javascript; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  2.  * ***** BEGIN LICENSE BLOCK *****
  3.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  4.  *
  5.  * The contents of this file are subject to the Mozilla Public License Version
  6.  * 1.1 (the "License"); you may not use this file except in compliance with
  7.  * the License. You may obtain a copy of the License at
  8.  * http://www.mozilla.org/MPL/
  9.  *
  10.  * Software distributed under the License is distributed on an "AS IS" basis,
  11.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12.  * for the specific language governing rights and limitations under the
  13.  * License.
  14.  *
  15.  * The Original Code is Mozilla Calendar code.
  16.  *
  17.  * The Initial Developer of the Original Code is
  18.  *   Joey Minta <jminta@gmail.com>
  19.  * Portions created by the Initial Developer are Copyright (C) 2006
  20.  * the Initial Developer. All Rights Reserved.
  21.  *
  22.  * Contributor(s):
  23.  *   Matthew Willis <lilmatt@mozilla.com>
  24.  *
  25.  * Alternatively, the contents of this file may be used under the terms of
  26.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  27.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  28.  * in which case the provisions of the GPL or the LGPL are applicable instead
  29.  * of those above. If you wish to allow use of your version of this file only
  30.  * under the terms of either the GPL or the LGPL, and not to allow others to
  31.  * use your version of this file under the terms of the MPL, indicate your
  32.  * decision by deleting the provisions above and replace them with the notice
  33.  * and other provisions required by the GPL or the LGPL. If you do not delete
  34.  * the provisions above, a recipient may use your version of this file under
  35.  * the terms of any one of the MPL, the GPL or the LGPL.
  36.  *
  37.  * ***** END LICENSE BLOCK ***** */
  38.  
  39. /**
  40.  * Prints a two column view of a week of events, much like a paper day-planner
  41.  */
  42.  
  43. function calWeekPrinter() {
  44.     this.wrappedJSObject = this;
  45. }
  46.  
  47. calWeekPrinter.prototype.QueryInterface =
  48. function QueryInterface(aIID) {
  49.     if (!aIID.equals(Components.interfaces.nsISupports) &&
  50.         !aIID.equals(Components.interfaces.calIPrintFormatter)) {
  51.         throw Components.results.NS_ERROR_NO_INTERFACE;
  52.     }
  53.  
  54.     return this;
  55. };
  56.  
  57. calWeekPrinter.prototype.getName =
  58. function weekPrint_getName() {
  59.     return calGetString("calendar", "weekPrinterName");
  60. };
  61. calWeekPrinter.prototype.__defineGetter__("name", calWeekPrinter.prototype.getName);
  62.  
  63. calWeekPrinter.prototype.formatToHtml =
  64. function weekPrint_format(aStream, aStart, aEnd, aCount, aItems, aTitle) {
  65.     // Create the e4x framework of the HTML document
  66.     var html = <html/>;
  67.     html.appendChild(
  68.             <head>
  69.                 <title>{aTitle}</title>
  70.                 <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/>
  71.                 <style type='text/css'/>
  72.             </head>);
  73.     html.head.style = ".main-table { font-size: 26px; font-weight:bold; }\n";
  74.     html.head.style += ".day-name { border: 1px solid #000; background-color: #e0e0e0; font-size: 12px; font-weight: bold; }\n";
  75.  
  76.     var body = <body/>;
  77.  
  78.     // helper: returns the passed item's startDate, entryDate or dueDate, in
  79.     //         that order. If the item doesn't have one of those dates, this
  80.     //         doesn't return.
  81.     function hasUsableDate(item) {
  82.         return item.startDate || item.entryDate || item.dueDate;
  83.     }
  84.  
  85.     // Clean out the item list so it only contains items we will want to
  86.     // include in the printout.
  87.     var filteredItems = aItems.filter(hasUsableDate);
  88.  
  89.     var calIEvent = Components.interfaces.calIEvent;
  90.     var calITodo = Components.interfaces.calITodo
  91.     function compareItems(a, b) {
  92.         // Sort tasks before events
  93.         if (a instanceof calIEvent && b instanceof calITodo) {
  94.             return 1;
  95.         }
  96.         if (a instanceof calITodo && b instanceof calIEvent) {
  97.             return -1;
  98.         }
  99.         if (a instanceof calIEvent) {
  100.             var startCompare = a.startDate.compare(b.startDate);
  101.             if (startCompare != 0) {
  102.                 return startCompare;
  103.             }
  104.             return a.endDate.compare(b.endDate);
  105.         }
  106.         var dateA = a.entryDate || a.dueDate;
  107.         var dateB = b.entryDate || b.dueDate;
  108.         return dateA.compare(dateB);
  109.     }
  110.     var sortedList = filteredItems.sort(compareItems);
  111.  
  112.     var weekFormatter = Components.classes["@mozilla.org/calendar/weektitle-service;1"]
  113.                                   .getService(Components.interfaces.calIWeekTitleService);
  114.  
  115.     // Start at the beginning of the week that aStart is in, and loop until
  116.     // we're at aEnd. In the loop we build the HTML table for each day, and
  117.     // get the day's items using getDayTd().
  118.     var start = aStart || sortedList[0].startDate || sortedList[0].entryDate ||
  119.                 sortList[0].dueDate;
  120.     ASSERT(start, "can't find a good starting date to print");
  121.  
  122.     var lastItem = sortedList[sortedList.length-1];
  123.     var end = aEnd || lastItem.startDate || lastItem.entryDate ||
  124.                lastItem.dueDate;
  125.     ASSERT(end, "can't find a good ending date to print");
  126.  
  127.     var date = start.startOfWeek;
  128.     var startOfWeek = getPrefSafe("calendar.week.start", 0);
  129.     date.day += startOfWeek;
  130.     // Make sure we didn't go too far ahead
  131.     if (date.compare(start) == 1) {
  132.         date.day -= 7;
  133.     }
  134.  
  135.     while(date.compare(end) == -1) {
  136.         var weekno = weekFormatter.getWeekTitle(date);
  137.         var weekTitle = calGetString("calendar", 'WeekTitle', [weekno]);
  138.         body.appendChild(
  139.                      <table border='0' width='100%' class='main-table'>
  140.                          <tr> 
  141.                              <td align='center' valign='bottom'>{weekTitle}</td>
  142.                          </tr>
  143.                      </table>);
  144.         var mainWeek = <table width='100%' height="90%" border='solid 1px;'/>
  145.  
  146.         // Create the <td> for each day, and put it into an array.
  147.         var dayTds = new Array();
  148.         for (var i = 0; i < 7 ; i++) {
  149.             dayTds[date.weekday] = this.getDayTd(date, sortedList);
  150.             date.day += 1;
  151.         }
  152.  
  153.         var monRow = <tr height="33%"/>;
  154.         monRow.appendChild(dayTds[1]); // Monday
  155.         monRow.appendChild(dayTds[4]); // Thursday
  156.         mainWeek.appendChild(monRow);
  157.  
  158.         var tueRow = <tr height="33%"/>;
  159.         tueRow.appendChild(dayTds[2]); // Tuesday
  160.         tueRow.appendChild(dayTds[5]); // Friday
  161.         mainWeek.appendChild(tueRow);
  162.  
  163.         var wedRow = <tr height="33%"/>;
  164.         wedRow.appendChild(dayTds[3]); // Wednesday
  165.  
  166.         // Saturday and Sunday are half-size
  167.         var satSunTd = <td height="33%"/>;
  168.         var weekendTable = <table border="1" width="100%" height="100%"/>;
  169.  
  170.         var satRow = <tr valign='top'/>;
  171.         satRow.appendChild(dayTds[6]); // Saturday
  172.         weekendTable.appendChild(satRow);
  173.  
  174.         var sunRow = <tr valign='top'/>;
  175.         sunRow.appendChild(dayTds[0]); // Sunday
  176.         weekendTable.appendChild(sunRow);
  177.  
  178.         satSunTd.appendChild(weekendTable);
  179.         wedRow.appendChild(satSunTd);
  180.         mainWeek.appendChild(wedRow);
  181.  
  182.         body.appendChild(mainWeek);
  183.         // Make sure each month gets put on its own page
  184.         body.appendChild(<br style="page-break-after: always;"/>);
  185.     }
  186.     html.appendChild(body);
  187.  
  188.     // Stream out the resulting HTML
  189.     var convStream = Components.classes["@mozilla.org/intl/converter-output-stream;1"]
  190.                                .getService(Components.interfaces.nsIConverterOutputStream);
  191.     convStream.init(aStream, 'UTF-8', 0, 0x0000);
  192.     convStream.writeString(html.toXMLString());
  193. };
  194.  
  195. calWeekPrinter.prototype.getDayTd =
  196. /**
  197.  * Given a calIDateTime and an array of items, this function creates an HTML
  198.  * table containing the items, using the appropriate formatting and colours.
  199.  */
  200. function weekPrint_getDayTable(aDate, aItems) {
  201.     // mainTd is the <td> element from the parent HTML table that will hold
  202.     // the child HTML tables containing the date string and this day's items.
  203.     var mainTd = <td border='1px solid black;' width="50%" valign='top'/>
  204.     var dateFormatter = Components.classes["@mozilla.org/calendar/datetime-formatter;1"]
  205.                                   .getService(Components.interfaces.calIDateTimeFormatter);
  206.     var defaultTimezone = calendarDefaultTimezone();
  207.     var dateString = dateFormatter.formatDateLong(aDate.getInTimezone(defaultTimezone));
  208.  
  209.     // Add the formatted date string (in its own child HTML table)
  210.     mainTd.appendChild(
  211.                      <table class='day-name' width='100%' style='border: 1px solid black;'>
  212.                          <tr> 
  213.                              <td align='center' valign='bottom'>{dateString}</td>
  214.                          </tr>
  215.                      </table>);
  216.  
  217.     // Add the formatted items (in their child HTML table)
  218.     var innerTable = <table valign='top' style='font-size: 10px;'/>;
  219.     for each (var item in aItems) {
  220.         var sDate = item.startDate || item.entryDate || item.dueDate;
  221.         var eDate = item.endDate || item.dueDate || item.entryDate;
  222.         if (sDate) {
  223.             sDate = sDate.getInTimezone(defaultTimezone);
  224.         }
  225.         if (eDate) {
  226.             eDate = eDate.getInTimezone(defaultTimezone);
  227.         }
  228.  
  229.         // End dates are exclusive. Adjust the eDate accordingly.
  230.         if (sDate && sDate.isDate && eDate) {
  231.             eDate = eDate.clone();
  232.             eDate.day -= 1;
  233.         }
  234.  
  235.         // If the item has no end date, or if the item's end date is aDate or
  236.         // is before aDate, skip to the next item.
  237.         if (!eDate || (eDate.compare(aDate) < 0)) {
  238.             continue;
  239.         }
  240.  
  241.         // No start date or a start date that's after the date we want is bad.
  242.         if (!sDate || (sDate.compare(aDate) > 0)) {
  243.             break;
  244.         }
  245.  
  246.         var time = "";
  247.         if (sDate && eDate && !sDate.isDate) {
  248.             time = dateFormatter.formatTime(sDate) + '-' + dateFormatter.formatTime(eDate);
  249.         } else if (sDate && !sDate.isDate) {
  250.             time = dateFormatter.formatTime(sDate);
  251.         } else if (eDate && !eDate.isDate) {
  252.             time = dateFormatter.formatTime(eDate);
  253.         }
  254.  
  255.         // Get calendar and category colours and apply them to the item's
  256.         // table cell.
  257.         var calColor = item.calendar.getProperty('color');
  258.         if (!calColor) {
  259.             calColor = "#A8C2E1";
  260.         }
  261.         var pb2 = Components.classes["@mozilla.org/preferences-service;1"]
  262.                             .getService(Components.interfaces.nsIPrefBranch2);
  263.         var catColor;
  264.         try {
  265.             catColor = pb2.getCharPref("calendar.category.color."+item.getProperty("CATEGORIES").toLowerCase());
  266.         } catch(ex) {}
  267.  
  268.         var style = 'font-size: 11px; background-color: ' + calColor + ';';
  269.         style += ' color: ' + getContrastingTextColor(calColor);
  270.         if (catColor) {
  271.             style += ' border: solid ' + catColor + ' 2px;';
  272.         }
  273.         var item = <tr>
  274.                        <td valign='top' align='left' style={style}>{time} {item.title}</td>
  275.                    </tr>;
  276.         innerTable.appendChild(item);
  277.     }
  278.     innerTable.appendChild(<p> </p>);
  279.     mainTd.appendChild(innerTable);
  280.     return mainTd;
  281. };
  282.